﻿using IOP.Extension.Convert;
using IOP.Protocols.MQTT.Extension;
using System;

namespace IOP.Protocols.MQTT.Package
{
    /// <summary>
    /// 订阅确认报文
    /// </summary>
    public struct SubackPackage : IMQTTPackage
    {
        /// <summary>
        /// 报文类型
        /// </summary>
        public ControlPacketType PacketType { get => ControlPacketType.SUBACK; }

        private uint _RemainingLength;
        /// <summary>
        /// 剩余长度
        /// </summary>
        public uint RemainingLength 
        {
            get => _RemainingLength + 2;
        }
        /// <summary>
        /// 报文标识符
        /// </summary>
        public ushort PacketIdentifier;

        private SubackCode[] _SubackCodes;
        /// <summary>
        /// 返回码
        /// </summary>
        public SubackCode[] SubackCodes
        {
            get
            {
                if (_SubackCodes == null) _SubackCodes = new SubackCode[0];
                return _SubackCodes;
            }
            set
            {
                if(_SubackCodes != value)
                {
                    if (_SubackCodes != null) _RemainingLength -= (uint)_SubackCodes.Length;
                    if (value != null)
                    {
                        _RemainingLength += (uint)value.Length;
                        _SubackCodes = value;
                    }
                    else _SubackCodes = new SubackCode[0];
                }
            }
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="packetId"></param>
        /// <param name="codes"></param>
        public SubackPackage(ushort packetId, SubackCode[] codes)
        {
            _RemainingLength = 0;
            _SubackCodes = new SubackCode[0];

            PacketIdentifier = packetId;
            SubackCodes = codes;
        }
        /// <summary>
        /// 转换为字节码
        /// </summary>
        /// <returns></returns>
        public Span<byte> ToBytes()
        {
            int remain = RemainingLength.GetRemainBytesLength();
            var length = RemainingLength + remain + 1;

            Span<byte> result = new byte[length];
            int index = 0;
            result[index++] = (byte)((int)PacketType << 4);
            RemainingLength.WriteRemainLengthToBytes(ref result, ref index);

            PacketIdentifier.WriteBytes(ref result, ref index);
            foreach(var item in SubackCodes)
            {
                result[index++] = (byte)item;
            }
            return result;
        }
    }
}
